using System.Collections.Generic;
using FibMatrix.Task;
using UnityEngine;
using UnityEngine.Profiling;

namespace FibMatrix
{
	[FM_Mono.IgnoreGen]
	public class AsyncLoadBundleFromDiskPipe : IResourceLoadPipe
	{
		public FMTask Handle(IResourcePipelineContext rawContext, out ResourceError error)
		{
			Profiler.BeginSample("AsyncLoadBundleFromDiskPipe.Handle");
			error = ResourceError.None;
			ResourcePipelineContext context = rawContext as ResourcePipelineContext;
			AssetBundleLoadItem mainHint = context.item as AssetBundleLoadItem;
			if (mainHint.bundleInfo.node.isAssetBundleFile == false)
				return null;

			List<BundleInfo> dependence = ResourceHelper.GetFixedFlatDependences(mainHint.bundleInfo);

			FMTaskList taskList = null;
			for (int i = dependence.Count - 1; i >= 0; --i)
			{
				BundleInfo bundleInfo = dependence[i];

				if (bundleInfo.urlMode != AssetBundleUrlMode.Remote)
				{
					if (bundleInfo.bundleHandle == null || !bundleInfo.bundleHandle.isCompleted)
					{
						taskList = taskList ?? new FMTaskList("TaskList", false, false);
						taskList.Add(PooledAsyncFMTask.Allocate(bundleInfo, context, GenerateBundleAsyncWork, GenerateAsyncWorkError, null));
					}
				}
				else
				{
					error = ResourceError.LoadModeInvalid;
					Debug.LogError($"AsyncLoadBundle failed:{bundleInfo.url}, {error}");
					break;
				}
			}

			if (error == ResourceError.None)
			{
				if (taskList != null)
				{
					taskList.asyncMode = true;
					taskList.Begin();
				}
			}

			Profiler.EndSample();
			return taskList;
		}

		private ResourceError GenerateAsyncWorkError(PooledAsyncFMTask task, IAsyncBase bundleLoadTask)
		{
			BundleLoadHandle handle = bundleLoadTask as BundleLoadHandle;
			if (handle == null || !handle.bundle)
			{
				BundleInfo item = task.context as BundleInfo;
				Debug.LogError($"AsyncLoadBundle failed:{item.url}, {ResourceError.FileNotFound}");
				return ResourceError.FileNotFound;
			}
			return ResourceError.None;
		}
		private static IAsyncBase GenerateBundleAsyncWork(PooledAsyncFMTask task)
		{
			BundleInfo item = task.context as BundleInfo;
			if (item.bundleHandle == null)
			{
				item.bundleHandle = BundleLoadManager.instance.LoadBundleAsync(item.url, item.md5);
			}
			return item.bundleHandle;
		}
	}
}
